package br.com.recipe.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

import br.com.recipe.exception.RecipeException;

public class HibernateSessionFactory {
	   private static SessionFactory sessionFactory;
	   private static Configuration configuration;
	   	   
	   /**
	    * 
	    * @return Configuration
	    * @throws LeadException 
	    */
	   private static Configuration getConfiguration() throws RecipeException {
	        if (configuration == null) {
	            try {
	                configuration = new Configuration().configure();
	            } catch (Throwable ex) {
	                throw new RecipeException("Initial Configuration creation failed.", ex);
	            }
	        }
	        return configuration;
	    }  
	      
	   /**
	    * Get a SessionFactory, createad from standard (hibernate.cfg.xml) 
	    * @return SessionFactory
	    */
	   private static SessionFactory getSessionFactory() throws RecipeException {
	     if(sessionFactory == null){
	          try {
	             configuration = getConfiguration(); 
	             sessionFactory = configuration.buildSessionFactory();
	        } catch (Throwable ex) {
	            throw new RecipeException("Initial SessionFactory creation failed.", ex);
	        }
	     }  
	     return sessionFactory;
	    }
	   
	   /**
	    * Generate Database
	    * @throws LeadException 
	    */
	    public static void generateDatabase() throws RecipeException {
	        try {
	            configuration = getConfiguration();
	            SchemaExport se = new SchemaExport(configuration);
	            se.create(true, true);
	        } catch (Throwable ex) {
	            throw new RecipeException("Creation of Database failed.", ex);
	        }
	    }
	    
	    /**
	     * Open and return a Session
	     * @return Session
	     * @throws LeadException 
	     */
	    public static Session getUnManagedSession() throws RecipeException {
	        return getSessionFactory().openSession();
	    }
	    
	    /**
	     * Reuse or open a Session (Managed)
	     * @return Session
	     */
	    public static Session getManagedSession() throws RecipeException {
	        return getManagedSession(true);
	    }
	    
	    /**
	     * Reuse or open a Session (Managed)
	     * @param forceTransaction
	     * @return @return Session
	     */    
	    public static Session getManagedSession(boolean forceTransaction) throws RecipeException {
	        Session session = getSessionFactory().openSession(); 
	        if(forceTransaction && ! session.getTransaction().isActive()){
	            session.beginTransaction();
	        }
	        return session;        
	    }
	    
	    /**
	     * Return a Transaction
	     * @return Transaction
	     */
	    public static Transaction getTransaction() throws RecipeException {
	        return getManagedSession(true).getTransaction();
	    }
}
